﻿@page "/Toolboxes"
@inject IToastService toastService
@using HardHatCore.HardHatC2Client.Plugin_BaseClasses;
@using HardHatCore.HardHatC2Client.Plugin_Management;
@using HardHatCore.HardHatC2Client.Utilities
@using HardHatCore.HardHatC2Client.Services
@using HardHatCore.HardHatC2Client.Components;
@using System.ComponentModel.Design.Serialization

<CascadingAuthenticationState>
<AuthorizeView Roles="TeamLead">
    <Authorized>
<h3>ToolBoxes</h3>
<MudTabs>
    <MudTabPanel Text="Commands">

    </MudTabPanel>
    <MudTabPanel Text="MITRE Tracking">
<MudDataGrid @ref="_table" T="ToolboxCommand" Items="@BodyContent" ReadOnly="false" Dense="true" Hover="true" CanCancelEdit="true" Height="700px" Elevation="10" Outlined="true" Striped="true"
                                     @bind-SelectedItem="selectedItem1" EditMode="DataGridEditMode.Form" StartedEditingItem="@StartedEditingItem" CanceledEditingItem="@CanceledEditingItem" CommittedItemChanges="@CommittedItemChanges"
                                     EditTrigger="DataGridEditTrigger.Manual" QuickFilter="@_quickFilter">
                            <ToolBarContent>
                                <MudText Typo="Typo.h6">Command OPSEC & MITRE ATT&CK Mapping</MudText>
                                <MudSpacer/>
                                <MudTextField Variant="Variant.Outlined" @bind-Value="searchString1" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
                            </ToolBarContent>
    <Columns>
        <PropertyColumn HeaderStyle="@setStyle(Settings.IsCheckedBox)" Property="x => x.commandName" Title="Command Name" CellStyleFunc="@_styleFunc" IsEditable="false"/>
                    <TemplateColumn CellClass="d-flex" HeaderStyle="@setStyle(Settings.IsCheckedBox)" Title="Opsec Status" CellStyleFunc="@_styleFunc" IsEditable="true">
            <CellTemplate Context="cellcontext">
                            <MudSelect Variant="Variant.Outlined" ValueChanged="(e)=>OpsecChanged(selectedItem1.commandName,e)" T="CommandItem.OpsecStatus">
                                @foreach (CommandItem.OpsecStatus opsec in Enum.GetValues(typeof(CommandItem.OpsecStatus)))
                {
                    <MudSelectItem Value="@opsec">@opsec</MudSelectItem>
                }
            </MudSelect>
            </CellTemplate>
        </TemplateColumn>
        <PropertyColumn HeaderStyle="@setStyle(Settings.IsCheckedBox)" Property="x=>x.MitreTechnique" Title="Mitre ATT&CK Map" CellStyleFunc="@_styleFunc" IsEditable="true"/>
        <TemplateColumn HeaderStyle="@setStyle(Settings.IsCheckedBox)" CellStyleFunc="@_styleFunc" CellClass="d-flex">
            <CellTemplate Context="editCellContext">
                <MudIconButton Icon="@Icons.Material.Outlined.Edit" OnClick="@editCellContext.Actions.StartEditingItemAsync" />
            </CellTemplate>
        </TemplateColumn>
    </Columns>
        <PagerContent>
                <MudDataGridPager T="ToolboxCommand" />
            </PagerContent>
    </MudDataGrid>
                </MudTabPanel>
</MudTabs>
        </Authorized>
</AuthorizeView>
<AuthorizeView Roles="Operator,Guest">
<Authorized>
    <MudTabs>
        <MudTabPanel Text="Commands">
                    <MudSelectExtended ValuePresenter="MudExtensions.Enums.ValuePresenter.ItemContent" Clearable="true" Class="mb-4 mt-4" T="Lazy<ICommandCodeView, CommandCodeViewBaseData>" Label="Implant Type" Variant="Variant.Filled" Required="true" @bind-value="CodeViewPlugin" RequiredError="Type is required!">
	    @foreach (var _codeViewPlugin in Plugin_Management.PluginService.pluginHub.CommandCodeView_Plugins)
	    {
		    string displayname = _codeViewPlugin.Metadata.Name;
		    if (displayname.Equals("Default",StringComparison.CurrentCultureIgnoreCase))
		    {
			    displayname = "Engineer";
		    }
		    <MudSelectItemExtended Value="@_codeViewPlugin"> @displayname </MudSelectItemExtended>
	    }
    </MudSelectExtended>
    <br>
    @if(CodeViewPlugin != null && !String.IsNullOrEmpty(CodeViewPlugin.Metadata.Name))
	    {
		    <CommandCodeView ImplantLang="@CodeViewPlugin.Metadata.CodeLang" ImplantSrc="@CodeViewPlugin.Metadata.ImplantSrc"></CommandCodeView>
	    }
    </MudTabPanel>
    <MudTabPanel Text="MITRE Tracking">
<MudDataGrid @ref="_table" T="ToolboxCommand" Items="@BodyContent" ReadOnly="true" Dense="true" Hover="true" CanCancelEdit="true" Height="700px" Elevation="10" Outlined="true" Striped="true"
                                     @bind-SelectedItem="selectedItem1" QuickFilter="@_quickFilter">
                            <ToolBarContent>
                                <MudText Typo="Typo.h6">Command OPSEC & MITRE ATT&CK Mapping</MudText>
                                <MudSpacer/>
                                <MudTextField @bind-Value="searchString1" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
                            </ToolBarContent>
    <Columns>
        <PropertyColumn HeaderStyle="@setStyle(Settings.IsCheckedBox)" Property="x => x.commandName" Title="Command Name" CellStyleFunc="@_styleFunc" IsEditable="false"/>
                    <TemplateColumn CellClass="d-flex" HeaderStyle="@setStyle(Settings.IsCheckedBox)" Title="Opsec Status" CellStyleFunc="@_styleFunc" IsEditable="false">
            <CellTemplate Context="cellcontext">
                            <MudSelect ValueChanged="(e)=>OpsecChanged(selectedItem1.commandName,e)" T="CommandItem.OpsecStatus">
                                @foreach (CommandItem.OpsecStatus opsec in Enum.GetValues(typeof(CommandItem.OpsecStatus)))
                {
                    <MudSelectItem Value="@opsec">@opsec</MudSelectItem>
                }
            </MudSelect>
            </CellTemplate>
        </TemplateColumn>
        <PropertyColumn HeaderStyle="@setStyle(Settings.IsCheckedBox)" Property="x=>x.MitreTechnique" Title="Mitre ATT&CK Map" CellStyleFunc="@_styleFunc" IsEditable="false"/>
        <TemplateColumn HeaderStyle="@setStyle(Settings.IsCheckedBox)" CellStyleFunc="@_styleFunc" CellClass="d-flex">
            <CellTemplate Context="editCellContext">
                <MudIconButton Icon="@Icons.Material.Outlined.Edit" OnClick="@editCellContext.Actions.StartEditingItemAsync" />
            </CellTemplate>
        </TemplateColumn>
    </Columns>
        <PagerContent>
                <MudDataGridPager T="ToolboxCommand" />
            </PagerContent>
    </MudDataGrid>
                </MudTabPanel>
</MudTabs>
</Authorized>
</AuthorizeView>
<AuthorizeView roles="TeamLead,Operator,Guest">
    <Authorized>
    </Authorized>
    <NotAuthorized>
        <h1 class="text-center">Not Authorized</h1>
        <UnAuthorizedDialogBox></UnAuthorizedDialogBox>
    </NotAuthorized>
</AuthorizeView>
</CascadingAuthenticationState>

@code {
    public static List<ToolboxCommand> BodyContent { get; set; } = new List<ToolboxCommand>();
    public static ToolboxCommand selectedItem1 { get; set; }
    public static ToolboxCommand ToolboxCommandBeforeEdit { get; set; } = new ToolboxCommand();
    private static ToastService _toastService = new ToastService();
    private string searchString1 = "";
    private MudDataGrid<ToolboxCommand> _table;
    private List<string> editEvents = new();
    private static Dictionary<string, CommandItem.OpsecStatus> CommandSelectedOpsecLevel { get; set; } = new();
    private static Lazy<ICommandCodeView, CommandCodeViewBaseData> CodeViewPlugin { get; set; }

    public class ToolboxCommand
    {
        public string commandName { get; set; }
        public CommandItem.OpsecStatus opsecStatus { get; set; }
        public string MitreTechnique { get; set; }
    }

    //functions
    private string setStyle(bool IsDark)
    {
        if (IsDark)
        {
            return "background:white; color:black;";
        }
        return "background:#333333; color:white;";
    }

    private void PageChanged(int i)
    {
        _table.CurrentPage = i - 1;
        _table.NavigateTo((Page)_table.CurrentPage);
    }

    private Func<ToolboxCommand, bool> _quickFilter => x =>
    {
        if (string.IsNullOrWhiteSpace(searchString1))
            return true;

        if (x.commandName.Contains(searchString1, StringComparison.OrdinalIgnoreCase))
            return true;

        if (x.opsecStatus.ToString().Contains(searchString1, StringComparison.OrdinalIgnoreCase))
            return true;

        if (x.MitreTechnique.Contains(searchString1, StringComparison.OrdinalIgnoreCase))
            return true;

        return false;
    };

    //create func that takes in a ReconCenterEntity.ReconCenterEntityProperty and returns string for the style where it allows multi line text 
    private Func<ToolboxCommand, string> _styleFunc => x =>
    {
        return "white-space: pre-line;";
    };

    private void AddEditionEvent(string message)
    {
        editEvents.Add(message);
        StateHasChanged();
    }

    // events
    void StartedEditingItem(ToolboxCommand item)
    {
        ToolboxCommandBeforeEdit.commandName = item.commandName;
        ToolboxCommandBeforeEdit.opsecStatus = item.opsecStatus;
        ToolboxCommandBeforeEdit.MitreTechnique = item.MitreTechnique;
        AddEditionEvent($"Event = StartedEditingItem, Data = {System.Text.Json.JsonSerializer.Serialize(item)}");

    }

    void CanceledEditingItem(ToolboxCommand item)
    {
        AddEditionEvent($"Event = CanceledEditingItem, Data = {System.Text.Json.JsonSerializer.Serialize(item)}");
    }

    void CommittedItemChanges(ToolboxCommand item)
    {
        //HardHatHubClient._hub.
        AddEditionEvent($"Event = CommittedItemChanges, Data = {System.Text.Json.JsonSerializer.Serialize(item)}");
    }

    private static void ShowSuccessToast(string successMessage)
    {
        _toastService.ShowSuccess(successMessage);
    }
    private static void ShowErrorToast(string errorMessage)
    {
        _toastService.ShowError(errorMessage);
    }


    public void OpsecChanged(string commandName, CommandItem.OpsecStatus opsecStatus)
    {
        string MitreTechnique = "";
        CommandSelectedOpsecLevel[commandName] = opsecStatus;
        var comValBase = PluginService.GetCommandValidationPlugin("Default");
        //find the matching helpmenuitem 
        foreach (CommandItem item in comValBase.CommandList)
        {
            if (item.Name == commandName)
            {
                MitreTechnique = item.MitreTechnique;
            }
        }
        HardHatHubClient._hub.FireMitreAndOpsecUpdate(commandName, opsecStatus,MitreTechnique);
        ShowSuccessToast($"Opsec Status for {commandName} has been changed to {opsecStatus}");
    }

    public static void updateOpsecStatusAndMitre(string commandName, CommandItem.OpsecStatus opsecStatus, string MitreTechnique)
    {
        CommandSelectedOpsecLevel[commandName] = opsecStatus;
        foreach (ToolboxCommand command in BodyContent)
        {
            if (command.commandName == commandName)
            {
                command.opsecStatus = opsecStatus;
                command.MitreTechnique = MitreTechnique;
            }
        }
    }

    protected override async Task OnInitializedAsync()
    {
        var comValBase = PluginService.GetCommandValidationPlugin("Default");
        _toastService = (ToastService)toastService;
        foreach (CommandItem menuItem in comValBase.CommandList)
        {
            ToolboxCommand command = new ToolboxCommand();
            command.commandName = menuItem.Name;
            command.opsecStatus = menuItem.Opsec;
            command.MitreTechnique = menuItem.MitreTechnique;
            BodyContent.Add(command);
        }
    //var timer = new Timer(new TimerCallback(_ => { InvokeAsync(StateHasChanged); }), null, 1000, 1000);
    }

}
